﻿using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;

public static class Extensions
{
    #region 字符串处理
    /// <summary>
    /// 因为不能保证在所有机器上string.GetHashCode都相同，所以我们需要在所有计算机上都相同的一个。
    /// </summary>
    public static int GetStableHashCode(this string text)
    {
        unchecked
        {
            int hash = 23;
            foreach (char c in text)
                hash = hash * 31 + c;
            return hash;
        }
    }
    #endregion

    #region 数字处理
    /// <summary>
    /// 转为int
    /// </summary>
    /// <param name="value"></param>
    /// <param name="errVal">转换失败时返回此数</param>
    /// <returns></returns>
    public static int ToInt(this string value, int errVal = 0)
    {
        int.TryParse(value, out errVal);
        return errVal;
    }
    /// <summary>
    /// 转为long
    /// </summary>
    /// <param name="value"></param>
    /// <param name="errVal">转换失败时返回此数</param>
    /// <returns></returns>
    public static long ToLong(this string value, long errVal = 0)
    {
        long.TryParse(value, out errVal);
        return errVal;
    }
    #endregion

    #region 数组处理
    /// <summary>
    /// 获取数组中最小值的索引
    /// </summary>
    public static int MinIndex<T>(this List<T> array)
    {
        return array.IndexOf(array.Min());
    }
    /// <summary>
    /// 获取时间数组中最新值的索引
    /// </summary>
    public static int MaxIndex<T>(this List<T> array)
    {
        return array.IndexOf(array.Max());
    }
    /// <summary>
    /// 检查列表是否重复
    /// </summary>
    public static bool HasDuplicates<T>(this List<T> list)
    {
        return list.Count != list.Distinct().Count();
    }
    /// <summary>
    /// 在列表中查找所有重复项
    /// </summary>
    public static List<U> FindDuplicates<T, U>(this List<T> list, Func<T, U> keySelector)
    {
        return list.GroupBy(keySelector)
            .Where(group => group.Count() > 1)
            .Select(group => group.Key).ToList();
    }
    #endregion

    #region 向量处理
    /// <summary>
    /// 获取Collider2D的ClosestPointOnBounds
    /// </summary>
    public static Vector2 ClosestPointOnBounds(this Collider2D collider, Vector2 position)
    {
        return collider.bounds.ClosestPoint(position);
    }
    /// <summary>
    /// 获取整数向量
    /// </summary>
    /// <param name="position"></param>
    /// <returns></returns>
    public static Vector3 GetIntValue(this Vector3 position)
    {
        int x = Mathf.RoundToInt(position.x); 
        int y = Mathf.RoundToInt(position.y);
        return new Vector3(x, y, 0);
    }
    #endregion

    #region 监听处理
    /// <summary>
    /// 设置监听事件，删除先前的，然后添加新的（适用于onClick等）
    /// </summary>
    public static void ResetListener(this UnityEvent uEvent, UnityAction call)
    {
        uEvent.RemoveAllListeners();
        uEvent.AddListener(call);
    }
    /// <summary>
    /// 设置带参数的监听事件，删除先前的，然后添加新的（适用于onEndEdit，onValueChanged等）
    /// </summary>
    public static void ResetListener<T>(this UnityEvent<T> uEvent, UnityAction<T> call)
    {
        uEvent.RemoveAllListeners();
        uEvent.AddListener(call);
    }
    #endregion
}
